<template>

    <div class="container" ref="container" :class="weatherClass, edgeClass" @mouseleave="mouseHandler(false)">
        <svg width="0" height="0" style="display: none">
            <filter id="filter">
                <feTurbulence type="fractalNoise" baseFrequency=".01" numOctaves="10" />
                <feDisplacementMap in="SourceGraphic" scale="180" />
            </filter>
        </svg>
        <div class="now">
            <div class="location">{{ adInfo.adInfo.province }}{{ adInfo.adInfo.city }}{{ adInfo.adInfo.district }}</div>
            <span>{{ now?.now.temp }}°c</span>
            <i :class="'qi-' + now?.now.icon + isDark(now?.now.obsTime.slice(11, 16))"></i>
            <span :title="now?.now.text">{{ now?.now.text }}</span>
        </div>
        <CardComponent title=" 24小时天气预报" :flag="flag.flag1" @open="openCard($event, 1)" class="hour24">
            <div class="container24" v-if="hours24">
                <template v-for="( item, _index ) in   hours24.hourly " :key="_index">
                    <div class="item">
                        <span class="temp">{{ item.temp }}</span>
                        <i :class="'qi-' + item.icon + isDark(item.fxTime.slice(11, 16))"></i>
                        <span class="text">{{ item.text }}</span>
                        <span class="time">{{ item.fxTime.slice(11, 16) }}</span>
                    </div>
                </template>
            </div>
        </CardComponent>
        <CardComponent title="7天天气预报" :flag="flag.flag2" @open="openCard($event, 2)" class="day7">
            <div class="container24" v-if="days7">
                <template v-for="( item, _index ) in   days7.daily " :key="_index">
                    <div class="item">
                        <p class="temp">
                            <span class="max">{{ item.tempMax }}</span>/
                            <span class="min">{{ item.tempMin }}</span>
                        </p>
                        <span class="icon">
                            <i :class="'qi-' + item.iconDay"></i>/<i :class="'qi-' + item.iconNight + '-fill'"></i>
                        </span>
                        <span class="text">{{ item.textDay }}/{{ item.textNight }}</span>
                        <span class="time">{{ item.fxDate.slice(5) }}</span>
                    </div>
                </template>
            </div>
        </CardComponent>
        <div class="refer">更新时间：{{ now?.updateTime.replace('T', ' ').slice(0, 16) }}</div>
        <div class="minWin" @mouseover="mouseHandler(true)">
            {{ now?.now.temp }}
            <i :class="'qi-' + now?.now.icon"></i>
        </div>
    </div>
</template>

<script setup lang="ts">
import type { WeatherApiResponse, Hour24, Weather15ApiResponse } from '@renderer/types/axios'
import { getGeoApi, getWeatherApi, getWeather24Api, getWeather7Api } from '@renderer/api'
import CardComponent from '@renderer/components/card.vue'
import { watch, ref, computed, nextTick } from 'vue'
import useAdInfo from '@renderer/store/adStore'

const adInfo = useAdInfo()
const now = ref<WeatherApiResponse>()
const hours24 = ref<Hour24>()
const locationId = ref<string>("")
const days7 = ref<Weather15ApiResponse>()
const flag = ref<{ flag1: boolean, flag2: boolean }>({
    flag1: true,
    flag2: false
})
const edgeClass = ref('')
const drag = ref<string>('no-drag')
const mouse = ref<boolean>(false)
const container = ref<HTMLElement>()

async function getWeather() {
    const prev = new Date(now.value?.updateTime || 0)
    if (Date.now() - prev.getTime() < 1000 * 60 * 5) return
    if (adInfo.add) {
        locationId.value = adInfo.add.id
        const w = await getWeatherApi(locationId.value)
        if (w.data.code == '200') {
            now.value = w.data
        }
    } else if (adInfo.adInfo.adcode) {
        const res = await getGeoApi(adInfo.adInfo.adcode || adInfo.add)
        if (res.status == 200) {
            locationId.value = res.data.location[0].id
            adInfo.setAddress({ id: res.data.location[0].id, name: res.data.location[0].name })
            const w = await getWeatherApi(locationId.value)
            if (w.data.code == '200') {
                now.value = w.data
            }
        } else {
            return
        }
    }
    rainSet()
    cloudSet()
    snowSet()
}
async function getWeather24() {
    const prev = new Date(hours24.value?.updateTime || 0)
    if (Date.now() - prev.getTime() < 1000 * 60 * 30) return
    if (adInfo.adInfo.adcode || adInfo.add) {
        hours24.value = (await getWeather24Api(locationId.value)).data
    }
}
async function getWeather7Days() {
    const prev = new Date(days7.value?.updateTime || 0)
    if (Date.now() - prev.getTime() < 1000 * 60 * 60 * 12) return
    if (adInfo.adInfo.adcode || adInfo.add) {
        days7.value = (await getWeather7Api(locationId.value)).data
    }
}
function openCard(val: boolean, id: number) {
    switch (id) {
        case 1:
            flag.value.flag1 = !val
            flag.value.flag2 = val
            break
        case 2:
            flag.value.flag1 = val
            flag.value.flag2 = !val
            break
    }
    if (flag.value.flag2) {
        getWeather7Days()
    }
    if (flag.value.flag1) {
        getWeather24()
    }
}
function mouseHandler(val: boolean) {
    if (!mouse.value) {
        mouse.value = true
        window.api.mouseover(val)
        setTimeout(() => {
            mouse.value = false
        }, 50)
    }
}
function isDark(time?: string) {
    const max = 420 // 08:00 转为分钟
    const min = 1200 // 20:00 转为分钟
    if (time) {
        const a = time.split(':')
        const b = Number(a[0]) * 60 + Number(a[1])
        if (b <= max || b >= min) {
            return '-fill'
        }
    }
    return ''
}

watch(
    adInfo,
    async (_val) => {
        await getWeather()
    },
)
const weatherClass = computed(() => {
    if (now.value?.now.text.indexOf('雪') != -1) return "snow"
    if (now.value?.now.text.indexOf('云') != -1) return "cloud"
    if (now.value?.now.text.indexOf('阴') != -1) return "cloud"
    if (now.value?.now.text.indexOf('晴') != -1) {
        const dark = isDark(now.value?.now.obsTime.slice(11, 16))
        if (dark == '-fill') {
            return 'moon'
        } else {
            return 'sun'
        }
    }
    if (now.value?.now.text.indexOf('雨') != -1) return "rain"
    return ""
})
const sunshine = computed(() => {
    const number = Math.min(Math.max(parseInt(now.value?.now.temp || '0') * 1.5, 30), 60)
    return { number, string: number + 'px' }
})

nextTick(async () => {
    cloudSet()
    await getWeather()
    await getWeather24()
})

window.api.update(async () => {
    await getWeather()
    await getWeather24()
})
window.api.edge((edge) => {
    switch (edge) {
        case 'n':
            edgeClass.value = ''
            drag.value = 'no-drag'
            break
        case 'l':
            edgeClass.value = 'left'
            drag.value = 'drag'
            break
        case 'r':
            edgeClass.value = 'right'
            drag.value = 'drag'
            break
    }
})

function rainSet() {
    if (weatherClass.value != 'rain') return
    setTimeout(() => {
        let el = document.createElement('div')
        el.setAttribute('class', 'raindrop')
        el.style.left = Math.random() * 100 + '%'
        container.value?.appendChild(el)
        setTimeout(() => {
            container.value?.removeChild(el)
        }, 2500 + Math.random() * 2000)
        rainSet()
    }, 1000 / Math.max(Math.min(parseInt(now.value?.now.precip || '0'), 100), 2))
}
function snowSet() {
    if (weatherClass.value != 'snow') return
    setTimeout(() => {
        let el = document.createElement('div')
        el.setAttribute('class', 'snowflake')
        el.style.left = Math.random() * 100 + '%'
        container.value?.appendChild(el)
        setTimeout(() => {
            container.value?.removeChild(el)
        }, 2000 + Math.random() * 500)
        snowSet()
    }, 300 + Math.random() * 200)
}
function cloudSet() {
    if (weatherClass.value != 'cloud') return
    let el = document.createElement('div')
    const cloudInt = parseInt(now.value?.now.cloud || '0')
    el.setAttribute('class', 'cloud-circle')
    el.style.width = (30 + Math.random() * 100) + 'px'
    el.style.height = (10 + Math.random() * 50) + 'px'
    el.style.top = (-400 + Math.random() * 40) + 'px'
    el.style.opacity = 0.01 + Math.random() + ''
    container.value?.appendChild(el)
    setTimeout(() => {
        container.value?.removeChild(el)
    }, 150000)
    setTimeout(() => {
        cloudSet()
    }, Math.max(5, Math.min(100 - cloudInt, 50)) * 1000)
}
</script>

<style lang="scss" scoped>
.container {
    border-radius: 8px;
    overflow: hidden;
    background: linear-gradient(-160deg, var(--color-background-start), var(--color-background-end));
    color: var(--color-text);
    position: relative;

    &.sun::after {
        content: '';
        display: block;
        position: absolute;
        left: 0px;
        top: 0px;
        width: 50px;
        height: 50px;
        transform: translate(calc(100vw + v-bind('sunshine.string')), calc(0px - v-bind('sunshine.string')));
        border-radius: 50%;
        box-shadow: 0 0 50px v-bind('sunshine.string') #ffff00e6;
        background: radial-gradient(circle at center, #ff4621, #ffdc17);
        animation: sun-move 120s linear infinite;
    }

    &.moon .now {
        background-image: url('@renderer/assets/moon.svg');
        background-repeat: no-repeat;
        background-size: cover;
        background-position: center;
    }

    @media screen and (max-width:100px) {

        &.left,
        &.right {
            width: 22px;
            height: 68px;

            .now,
            .hour24,
            .day7,
            .refer {
                display: none;
            }


            .minWin {
                display: block;
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                justify-content: space-evenly;
                align-items: center;
                font-size: 16px;
                font-weight: 500;
                cursor: pointer;
                z-index: 2;
            }
        }
    }

    &.left {
        border-radius: 0 5px 5px 0;
    }

    &.right {
        border-radius: 5px 0 0 5px;
    }

    .minWin {
        display: none;
    }

    .now {
        height: 123px;
        font-size: 50px;
        display: flex;
        font-weight: 600;
        justify-content: center;
        align-items: center;
        gap: 12px;
        position: relative;
        padding-top: 20px;
        position: relative;
        -webkit-app-region: drag;
        z-index: 2;
        text-shadow: 0 0 6px #00000099;

        .location {
            position: absolute;
            font-size: 12px;
            left: 8px;
            top: 8px;
        }

        span:last-of-type {
            font-size: 14px;
            white-space: nowrap;
            max-width: 90px;
            overflow: hidden;
            text-overflow: ellipsis
        }

        .drag {
            position: absolute;
            left: 2px;
            top: 2px;
            right: 2px;
            bottom: 2px;
            z-index: -1;
            -webkit-app-region: drag;
        }
    }

    .container24 {
        display: flex;
        width: max-content;
        z-index: 2;

        .item {
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            align-items: center;
            flex: 0 0 calc((290px + 1px) / 5);
            user-select: none;
            font-size: 20px;
            margin: 3px auto;
            border-right: 1px solid #cccccc70;
            gap: 3px;

            .text,
            .time {
                font-size: 14px;
            }
        }
    }

    .day7 {
        z-index: 2;

        .container24 {

            .item {
                flex: 0 0 calc((290px + 1px) / 4);
                gap: 5px;
                margin-top: 10px;

                .icon {
                    font-size: 16px;
                }

                .text {
                    font-size: 12px;
                }

                .temp {
                    display: flex;

                    .max {
                        font-size: 18px;
                        position: relative;
                        top: -3px;
                    }

                    .min {
                        font-size: 16px;
                        position: relative;
                        top: 8px;
                    }
                }
            }
        }
    }

    .refer {
        z-index: 2;
        font-size: 8px;
        padding: 3px 9px;
        text-align: right;
        background: var(--color-tab-background);
        user-select: none;
    }

    .hour24 {
        z-index: 2;
    }

    @keyframes sun-move {
        0% {
            transform: translate(100vw, -100%);
        }

        5% {
            transform: translate(calc(95vw - 50%), -95%);
        }

        10% {
            transform: translate(calc(90vw - 50%), -70%);
        }

        45% {
            transform: translate(calc(55vw - 50%), -5%);
        }

        55% {
            transform: translate(calc(45vw - 50%), -5%);
        }

        90% {
            transform: translate(calc(10vw - 50%), -70%);
        }

        95% {
            transform: translate(calc(5vw - 50%), -95%);
        }

        100% {
            transform: translate(-100%, -100%);
        }
    }

    @keyframes moon-move {
        from {
            transform: translate(-30%)
        }

        to {
            transform: translate(calc(100vw + 50%));
        }
    }
}
</style>